---
title: Carbon 类
description: Carbon 类详细文档
---

# Carbon 类详细文档

## 简介

Carbon 是 PHP DateTime 类的一个简单扩展，它继承了 PHP 原生的 DateTime 类的所有功能，同时提供了更多人性化和开发者友好的方法来处理日期和时间。Carbon 是 Laravel 框架中默认的日期时间处理库。

## 安装

```bash
composer require nesbot/carbon
```

## 基本用法

### 引入命名空间

```php
use Carbon\Carbon;
```

### 创建 Carbon 实例

```php
// 获取当前时间（使用应用配置的时区）
$now = Carbon::now();

// 获取当前时间（指定时区）
$nowInShanghai = Carbon::now('Asia/Shanghai');

// 从时间戳创建（默认使用 UTC 时区）
$fromTimestamp = Carbon::createFromTimestamp(1609459200);

// 从时间戳创建（指定时区）
$fromTimestampWithTz = Carbon::createFromTimestamp(1609459200, 'Asia/Shanghai');

// 从日期字符串创建
$fromString = Carbon::parse('2023-01-15 13:30:45');

// 创建特定日期时间
$specificDate = Carbon::create(2023, 1, 15, 13, 30, 45, 'Asia/Shanghai');
```

## 时区处理

### 设置默认时区

```php
// 全局设置默认时区
Carbon::setTestNow();
date_default_timezone_set('Asia/Shanghai');

// 在 Laravel 中，可以在 config/app.php 中设置
// 'timezone' => 'Asia/Shanghai',
```

### 时区转换

```php
// 创建一个 Carbon 实例
$date = Carbon::now('UTC');

// 转换到另一个时区（不修改原实例）
$dateInShanghai = $date->copy()->setTimezone('Asia/Shanghai');

// 直接修改实例的时区
$date->setTimezone('Asia/Shanghai');

// 获取当前时区
$timezone = $date->timezone;
$tzName = $date->tzName; // 时区名称，如 'Asia/Shanghai'
```

### 时区注意事项

1. **createFromTimestamp 方法**：默认使用 UTC 时区，除非明确指定时区参数
```php
// 这会使用 UTC 时区
$date = Carbon::createFromTimestamp(time());

// 这会使用指定的时区
$date = Carbon::createFromTimestamp(time(), 'Asia/Shanghai');
   ```

2. **now 方法**：使用应用配置的默认时区，或者指定的时区
```php
// 使用应用配置的时区
$date = Carbon::now();

// 使用指定的时区
$date = Carbon::now('Asia/Shanghai');
   ```

## 格式化输出

```php
$date = Carbon::now();

// 预定义格式
$date->toDateString();                   // 2023-01-15
$date->toTimeString();                   // 13:30:45
$date->toDateTimeString();               // 2023-01-15 13:30:45
$date->toFormattedDateString();          // Jan 15, 2023
$date->toDayDateTimeString();            // Sun, Jan 15, 2023 1:30 PM

// 自定义格式
$date->format('Y-m-d H:i:s');            // 2023-01-15 13:30:45
$date->format('l jS \\of F Y h:i:s A');  // Sunday 15th of January 2023 01:30:45 PM

// ISO 8601 格式
$date->toIso8601String();                // 2023-01-15T13:30:45+08:00

// RFC 格式
$date->toRfc2822String();                // Sun, 15 Jan 2023 13:30:45 +0800
$date->toRfc3339String();                // 2023-01-15T13:30:45+08:00

// Unix 时间戳
$date->timestamp;                        // 1673760645
```

## 日期时间修改

### 设置日期时间组件

```php
$date = Carbon::now();

// 设置年、月、日
$date->year(2024);                       // 设置年份为 2024
$date->month(3);                         // 设置月份为 3（三月）
$date->day(15);                          // 设置日期为 15 号

// 设置时、分、秒
$date->hour(14);                         // 设置小时为 14（下午 2 点）
$date->minute(30);                       // 设置分钟为 30
$date->second(0);                        // 设置秒数为 0

// 链式调用
$date->year(2024)->month(3)->day(15)->hour(14)->minute(30)->second(0);
```

### 日期时间加减

```php
$date = Carbon::now();

// 加法
$date->addYear();                        // 加 1 年
$date->addYears(2);                      // 加 2 年
$date->addMonth();                       // 加 1 个月
$date->addMonths(3);                     // 加 3 个月
$date->addDay();                         // 加 1 天
$date->addDays(5);                       // 加 5 天
$date->addHours(3);                      // 加 3 小时
$date->addMinutes(15);                   // 加 15 分钟
$date->addSeconds(30);                   // 加 30 秒

// 减法
$date->subYear();                        // 减 1 年
$date->subYears(2);                      // 减 2 年
$date->subMonth();                       // 减 1 个月
$date->subMonths(3);                     // 减 3 个月
$date->subDay();                         // 减 1 天
$date->subDays(5);                       // 减 5 天
$date->subHours(3);                      // 减 3 小时
$date->subMinutes(15);                   // 减 15 分钟
$date->subSeconds(30);                   // 减 30 秒

// 链式调用
$date->addYear()->addMonths(3)->subDays(2)->addHours(5);
```

### 日期时间修改器

```php
$date = Carbon::now();

// 开始和结束
$date->startOfDay();                     // 设置为当天的开始 (00:00:00)
$date->endOfDay();                       // 设置为当天的结束 (23:59:59)
$date->startOfMonth();                   // 设置为当月的第一天的开始
$date->endOfMonth();                     // 设置为当月的最后一天的结束
$date->startOfYear();                    // 设置为当年的第一天的开始
$date->endOfYear();                      // 设置为当年的最后一天的结束
$date->startOfWeek();                    // 设置为当周的第一天的开始
$date->endOfWeek();                      // 设置为当周的最后一天的结束

// 下一个和上一个
$date->next(Carbon::MONDAY);             // 设置为下一个星期一
$date->previous(Carbon::MONDAY);         // 设置为上一个星期一

// 其他修改器
$date->firstOfMonth();                   // 设置为当月的第一天
$date->lastOfMonth();                    // 设置为当月的最后一天
$date->nthOfMonth(2, Carbon::MONDAY);    // 设置为当月的第二个星期一
```

## 日期时间比较

```php
$date1 = Carbon::create(2023, 1, 15);
$date2 = Carbon::create(2023, 2, 20);
$now = Carbon::now();

// 基本比较
$date1->eq($date2);                      // 是否相等
$date1->ne($date2);                      // 是否不相等
$date1->gt($date2);                      // 是否大于
$date1->gte($date2);                     // 是否大于等于
$date1->lt($date2);                      // 是否小于
$date1->lte($date2);                     // 是否小于等于

// 其他比较方法
$date1->equalTo($date2);                 // 是否相等
$date1->notEqualTo($date2);              // 是否不相等
$date1->greaterThan($date2);             // 是否大于
$date1->greaterThanOrEqualTo($date2);    // 是否大于等于
$date1->lessThan($date2);                // 是否小于
$date1->lessThanOrEqualTo($date2);       // 是否小于等于

// 最大和最小
$maxDate = Carbon::maximum($date1, $date2);  // 返回较大的日期
$minDate = Carbon::minimum($date1, $date2);  // 返回较小的日期

// 检查是否在某个范围内
$now->between($date1, $date2);           // 是否在两个日期之间
$now->betweenIncluded($date1, $date2);   // 是否在两个日期之间（包含边界）

// 检查特定条件
$now->isWeekday();                       // 是否是工作日
$now->isWeekend();                       // 是否是周末
$now->isYesterday();                     // 是否是昨天
$now->isToday();                         // 是否是今天
$now->isTomorrow();                      // 是否是明天
$now->isFuture();                        // 是否是未来
$now->isPast();                          // 是否是过去
$now->isLeapYear();                      // 是否是闰年
```

## 差异计算

```php
$date1 = Carbon::create(2023, 1, 15);
$date2 = Carbon::create(2023, 2, 20);

// 差异（默认单位：秒）
$diff = $date1->diffInSeconds($date2);    // 相差的秒数
$diffAbs = $date1->diffInSeconds($date2, false);  // 相差的秒数（带符号）

// 其他单位的差异
$date1->diffInMinutes($date2);           // 相差的分钟数
$date1->diffInHours($date2);             // 相差的小时数
$date1->diffInDays($date2);              // 相差的天数
$date1->diffInWeeks($date2);             // 相差的周数
$date1->diffInMonths($date2);            // 相差的月数
$date1->diffInYears($date2);             // 相差的年数

// 人性化差异描述
$date1->diffForHumans();                 // 相对于现在的描述，如「3 小时前」
$date1->diffForHumans($date2);           // 相对于指定日期的描述，如「1 个月前」
```

## 本地化和国际化

```php
// 设置语言
Carbon::setLocale('zh_CN');

$date = Carbon::now();

// 本地化输出
$date->isoFormat('LLLL');                // 完整的日期时间，如「2023年1月15日星期日 13时30分45秒」
$date->isoFormat('LLL');                 // 长日期时间，如「2023年1月15日 13:30」
$date->isoFormat('LL');                  // 长日期，如「2023年1月15日」
$date->isoFormat('L');                   // 短日期，如「2023/01/15」

// 人性化差异（本地化）
$date->subDays(3)->diffForHumans();       // 「3 天前」
```

## 序列化和反序列化

```php
$date = Carbon::now();

// 序列化
$serialized = serialize($date);

// 反序列化
$unserialized = unserialize($serialized);

// JSON 序列化
$json = json_encode($date);

// 从 JSON 创建
$fromJson = Carbon::parse(json_decode($json));
```

## 测试辅助方法

```php
// 设置固定的「当前时间」用于测试
Carbon::setTestNow(Carbon::create(2023, 1, 15, 12, 0, 0));

// 现在所有的 now() 调用都会返回这个固定时间
$now = Carbon::now(); // 2023-01-15 12:00:00

// 清除测试时间
Carbon::setTestNow();
```

## 在 Laravel 中使用 Carbon

在 Laravel 中，Carbon 已经被集成，并且可以通过多种方式使用：

```php
// 直接使用 Carbon 类
use Carbon\Carbon;
$now = Carbon::now();

// 使用 now() 辅助函数
$now = now();

// 在 Eloquent 模型中处理日期
class User extends Model
{
    protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at',
        'last_login_at', // 自定义日期字段
    ];
}

// 然后可以像使用 Carbon 实例一样使用这些日期属性
$user = User::first();
$user->created_at->format('Y-m-d');
$user->last_login_at->diffForHumans();
```

## 常见问题和最佳实践

### 1. 时区处理

- 在应用中保持一致的时区策略，通常建议在数据库中存储 UTC 时间，然后在显示时转换为用户的本地时区
- 使用 `createFromTimestamp()` 时，始终明确指定时区，避免默认使用 UTC 导致的问题
- 在 Laravel 中，确保在 `config/app.php` 中正确设置了应用的默认时区

### 2. 不可变性

默认情况下，Carbon 实例是可变的，这意味着修改方法会改变原始实例：

```php
$date = Carbon::now();
$date->addDay(); // $date 被修改
```

如果需要保持原始实例不变，可以使用 `copy()` 方法：

```php
$date = Carbon::now();
$tomorrow = $date->copy()->addDay(); // $date 保持不变
```

或者使用 CarbonImmutable：

```php
use Carbon\CarbonImmutable;

$date = CarbonImmutable::now();
$tomorrow = $date->addDay(); // 返回新实例，$date 保持不变
```

### 3. 性能考虑

- 避免在循环中重复创建 Carbon 实例
- 对于大量日期操作，考虑使用原生 PHP DateTime 或时间戳
- 使用 `setTestNow()` 可以提高测试性能

## 总结

Carbon 是一个功能强大且易于使用的日期时间处理库，它提供了丰富的方法来创建、格式化、修改和比较日期时间。在 Laravel 应用中，正确理解和使用 Carbon 可以大大简化日期时间相关的操作，特别是在处理不同时区和本地化需求时。

希望这个详细文档能帮助您更好地理解和使用 Carbon 类！